package com.ideaaedi.commonds.rank;


import com.ideaaedi.commonds.sort.DefaultSortSupporter;
import com.ideaaedi.commonds.sort.SortStrategy;
import com.ideaaedi.commonds.sort.SortSupporter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 排名器
 * <br />
 * P.S. 这是稳定的
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
public class Ranker<T extends Rankable<T>> {
    
    private final SortSupporter<T> sortSupporter;
    
    private final RankSupporter<T> rankSupporter;
    
    private Ranker(SortSupporter<T> sortSupporter, DefaultRankSupporter<T> rankSupporter) {
        this.sortSupporter = sortSupporter;
        this.rankSupporter = rankSupporter;
    }
    
    public static <T extends Rankable<T>> Ranker<T> defaultInstance(){
        return new Ranker<>(new DefaultSortSupporter<T>(), new DefaultRankSupporter<T>());
    }
    
    
    public static <T extends Rankable<T>> Ranker<T> buildInstance(SortSupporter<T> sortSupporter, DefaultRankSupporter<T> rankSupporter){
        return new Ranker<>(new DefaultSortSupporter<T>(), new DefaultRankSupporter<T>());
    }
    
    /**
     * @see Ranker#generateRankingList(Collection, boolean, SortStrategy, RankStrategy)
     */
    public List<T> generateRankingList(Collection<T> dataList, boolean asc) {
        return this.generateRankingList(dataList, asc, SortStrategy.AUTO, RankStrategy.INDEX_POSTPONED_IF_SAME);
    }
    
    /**
     * 排序
     *
     * @param dataList
     *         要被排名的数据集
     * @param asc
     *            true-正向， false-反向
     * @param sortStrategy
     *         排序策略
     * @param rankStrategy
     *         排名策略
     *
     * @return 排序后的数据
     */
    public List<T> generateRankingList(Collection<T> dataList, boolean asc, SortStrategy sortStrategy, RankStrategy rankStrategy) {
        // -> 数据整理
        if (dataList == null || dataList.size() == 0) {
            return new ArrayList<>();
        }
        List<T> nullList = new ArrayList<>(16);
        List<T> nonNullList = new ArrayList<>(16);
        dataList.forEach(x -> {
                    if (x == null) {
                        nullList.add(null);
                    } else {
                        nonNullList.add(x);
                    }
                }
        );
        if (nonNullList.size() == 0) {
            return nullList;
        }
        // -> 排序
        List<T> nonNullSortedList = sortSupporter.doSort(nonNullList, sortStrategy, asc);
        // -> 排名
        List<T> sortedAndRankedList = rankSupporter.doRank(nonNullSortedList, rankStrategy);
        // 将null元素， 放置在最后
        sortedAndRankedList.addAll(nullList);
        return sortedAndRankedList;
    }
    
}
